﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NetCoreCMS.Common;
using NetCoreCMS.IServices;
using NetCoreCMS.Models;
using NetCoreCMS.PayAPI.alipaymb;

namespace NetCoreCMS.Web.Areas.Payments.Controllers
{
    public class AlipayMBController : AreasController
    {
        public IUser_rechargeService _user_recharge { get; set; }
        public IOrdersService _orders { get; set; }
        public ISite_paymentService _site_payment { get; set; }
        public IPaymentService _payment { get; set; }
        public IUser_point_logService _user_point_log { get; set; }
        public IActionResult Index()
        {
            int site_payment_id = 0;
            //=============================获得订单信息================================
            string order_no = CMSRequest.GetFormString("pay_order_no", HttpContext).ToUpper();
            decimal order_amount = CMSRequest.GetFormDecimal("pay_order_amount", 0, HttpContext);
            string user_name = CMSRequest.GetFormString("pay_user_name", HttpContext);
            string subject = CMSRequest.GetFormString("pay_subject", HttpContext);
            //检查参数是否正确
            if (string.IsNullOrEmpty(order_no) || order_amount == 0)
            {
                return ToError("对不起，您提交的参数有误！");
            }
            //===============================判断订单==================================
            if (order_no.StartsWith("R")) //R开头为在线充值订单
            {
                User_recharge model = _user_recharge.GetModel(order_no);
                if (model == null)
                {
                    return ToError("对不起，您充值的订单号不存在或已删除！");
                }
                if (model.amount != order_amount)
                {
                    return ToError("对不起，您充值的订单金额与实际金额不一致！");
                }
                site_payment_id = model.payment_id; //站点支付方式ID
            }
            else //B开头为商品订单
            {
                Orders model = _orders.GetModel(order_no);
                if (model == null)
                {
                    return ToError("对不起，您支付的订单号不存在或已删除！");
                }
                if (model.order_amount != order_amount)
                {
                    return ToError("对不起，您支付的订单金额与实际金额不一致！");
                }
                site_payment_id = model.payment_id; //站点支付方式ID
            }
            if (user_name != "")
            {
                user_name = "支付会员：" + user_name;
            }
            else
            {
                user_name = "匿名用户";
            }
            var site_paymentModel = _site_payment.GetList().FirstOrDefault(a => a.payment_id == site_payment_id);
            var paymentModel = _payment.GetModel(site_payment_id);
            //===============================建立请求==================================
            string GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?"; //支付宝新网关地址
            Dictionary<string, string> sParaTemp = new Dictionary<string, string>();
            Config config = new Config(site_paymentModel, paymentModel, sysConfig,HttpContext);
            sParaTemp.Add("partner", config.Partner);
            sParaTemp.Add("seller_id", config.Partner);
            sParaTemp.Add("_input_charset", config.Input_charset.ToLower());
            sParaTemp.Add("service", "alipay.wap.create.direct.pay.by.user");
            sParaTemp.Add("payment_type", "1");
            sParaTemp.Add("notify_url", config.Notify_url);
            sParaTemp.Add("return_url", config.Return_url);
            sParaTemp.Add("out_trade_no", order_no);
            sParaTemp.Add("subject", sysConfig.webname + "-" + subject);
            sParaTemp.Add("total_fee", order_amount.ToString());
            sParaTemp.Add("show_url", sysConfig.weburl);
            sParaTemp.Add("app_pay", "Y");//启用此参数可唤起钱包APP支付。
            sParaTemp.Add("body", user_name);

            //建立请求
            Submit submit = new Submit(site_paymentModel, paymentModel, sysConfig, HttpContext);
            string sHtmlText = submit.BuildRequest(GATEWAY_NEW, sParaTemp, "get", "确认");
            return Content(sHtmlText);
        }
        public IActionResult Notify_Url()
        {
            int site_payment_id = 0; //站点支付方式ID
            Dictionary<string, string> sPara = GetRequestPost();

            if (sPara.Count > 0)//判断是否有带返回参数
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(sPara["notify_data"]);
                string trade_no = xmlDoc.SelectSingleNode("/notify/trade_no").InnerText; //支付宝交易号
                string order_no = xmlDoc.SelectSingleNode("/notify/out_trade_no").InnerText.ToUpper(); //商户订单号
                string total_fee = xmlDoc.SelectSingleNode("/notify/total_fee").InnerText; //获取总金额
                string trade_status = xmlDoc.SelectSingleNode("/notify/trade_status").InnerText; //交易状态
                if (order_no.StartsWith("R")) //充值订单
                {
                    site_payment_id = _user_recharge.GetModel(order_no).payment_id;
                }
                else if (order_no.StartsWith("B")) //商品订单
                {
                    site_payment_id = _orders.GetModel(order_no).payment_id;
                }
                if (site_payment_id == 0)
                {
                    return Content("该订单号不存在");
                }
                var site_paymentModel = _site_payment.GetList().FirstOrDefault(a => a.payment_id == site_payment_id);
                var paymentModel = _payment.GetModel(site_payment_id);
                //找到站点支付方式ID开始验证
                Notify aliNotify = new Notify(site_paymentModel, paymentModel, sysConfig, HttpContext);
                bool verifyResult = aliNotify.VerifyNotify(sPara, Request.Form["sign"]);
                if (verifyResult)//验证成功
                {
                    try
                    {
                        if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                        {
                            if (order_no.StartsWith("R")) //充值订单
                            {
                                User_recharge model = _user_recharge.GetModel(order_no);
                                if (model == null)
                                {
                                    return Content("该订单号不存在");
                                }
                                if (model.status == 1) //已成功
                                {
                                    return Content("success");
                                }
                                if (model.amount != decimal.Parse(total_fee))
                                {
                                    return Content("订单金额和支付金额不相符");
                                }
                                bool result = _user_recharge.Confirm(order_no);
                                if (!result)
                                {
                                    return Content("修改订单状态失败");
                                }
                            }
                            else if (order_no.StartsWith("B")) //商品订单
                            {
                                Orders model = _orders.GetModel(order_no);
                                if (model == null)
                                {
                                    return Content("该订单号不存在");
                                }
                                if (model.payment_status == 2) //已付款
                                {
                                    return Content("success");
                                }
                                if (model.order_amount != decimal.Parse(total_fee))
                                {
                                    return Content("订单金额和支付金额不相符");
                                }
                                bool result = _orders.UpdateField(order_no, "trade_no='" + trade_no + "',status=2,payment_status=2,payment_time='" + DateTime.Now + "'");
                                if (!result)
                                {
                                    return Content("修改订单状态失败");
                                }
                                //扣除积分
                                if (model.point < 0)
                                {
                                    _user_point_log.Add(model.user_id, model.user_name, model.point, "换购扣除积分，订单号：" + model.order_no, false);
                                }
                            }
                            return Content("success");  //请不要修改或删除
                        }
                        else
                        {
                            return Content(trade_status);
                        }
                    }
                    catch (Exception ex)
                    {
                        return Content(ex.ToString());
                    }
                }
                else //验证失败
                {
                    return Content("fail");
                }
            }
            else
            {
                return Content("无通知参数");
            }
        }
        public IActionResult Pay()
        {
            return View();
        }
        public IActionResult Return_Url()
        {
            int site_payment_id = 0; //站点支付方式ID
            Dictionary<string, string> sPara = GetRequestGet();

            if (sPara.Count > 0)//判断是否有带返回参数
            {
                string order_no = CMSRequest.GetString("out_trade_no",HttpContext).ToUpper();//获取订单号
                string trade_no = CMSRequest.GetString("trade_no", HttpContext); //支付宝交易号
                string result = CMSRequest.GetString("result", HttpContext); //交易状态
                if (order_no.StartsWith("R")) //充值订单
                {
                    site_payment_id = _user_recharge.GetModel(order_no).payment_id;
                }
                else if (order_no.StartsWith("B")) //商品订单
                {
                    site_payment_id = _orders.GetModel(order_no).payment_id;
                }
                var site_paymentModel = _site_payment.GetList().FirstOrDefault(a => a.payment_id == site_payment_id);
                var paymentModel = _payment.GetModel(site_payment_id);
                //找到站点支付方式ID开始验证
                if (site_payment_id > 0)
                {
                    Notify aliNotify = new Notify(site_paymentModel, paymentModel, sysConfig, HttpContext);
                    bool verifyResult = aliNotify.VerifyReturn(sPara, Request.Query["sign"]);

                    if (verifyResult)//验证成功
                    {
                        if (result == "success")
                        {
                            //成功状态
                            return Redirect("/Web/Payment/Index?action=succeed&order_no=" + order_no);
                        }
                    }
                }
            }
            //失败状态
            return Redirect("/Web/Payment/Index?action=error");
        }
        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public Dictionary<string, string> GetRequestPost()
        {
            int i = 0;
            Dictionary<string, string> sArray = new Dictionary<string, string>();
            IFormCollection coll;
            coll = Request.Form;
            String[] requestItem = coll.Keys.ToArray();

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
            }

            return sArray;
        }
        /// <summary>
        /// 获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public Dictionary<string, string> GetRequestGet()
        {
            int i = 0;
            Dictionary<string, string> sArray = new Dictionary<string, string>();
            IQueryCollection coll;
            coll = Request.Query;
            String[] requestItem = coll.Keys.ToArray();

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Query[requestItem[i]]);
            }

            return sArray;
        }
    }
}